﻿using System;
using System.Globalization;
using Desjardins.Transaction;
using Medianamik.Core;
using Medianamik.Core.Logging;
using Medianamik.Core.Sugar;
using Medianamik.UI.Web.Shop.Data.Interfaces;
using Medianamik.UI.Web.MVP.Presentation;
using Medianamik.UI.Web.Shop.Data.Repositories;
using Medianamik.UI.Web.Shop.Services;
using StructureMap;
using IModel = Medianamik.UI.Web.Shop.Data.Interfaces.IModel;
using IOrderItem = Medianamik.UI.Web.Shop.Data.Interfaces.IOrderItem;
using IProduct = Medianamik.UI.Web.Shop.Data.Interfaces.IProduct;

namespace Medianamik.UI.Web.Shop.Presentation.Presenters
{
    public abstract class DesjardinsBeginPresenter<T, TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels> : ModulePresenter<T>
        where T : IDesjardinsView
        where TOrder : IOrder<TOrderItem>
        where TOrderItem : IOrderItem
        where TShoppingCart : IShoppingCart<TShoppingCartItem, TModel>
        where TProduct : IProduct
        where TModel : IModel
        where TShoppingCartItem : IShoppingCartItem<TModel>
    {
        public abstract Guid PaymentProviderId { get; }
        public const string PaymentProviderName = "Desjardins";

        private readonly IPaymentProviderBaseRepository<Data.Desjardins> _paymentProviderBaseRepository =
                ObjectFactory.GetInstance<IPaymentProviderBaseRepository<Data.Desjardins>>();

        private IDesjardins _currentNode;
        public IDesjardins CurrentNode { 
            get { return _currentNode ?? (_currentNode = GetCurrentNode()); }
        }

        private IDesjardins GetCurrentNode()
        {
            return _paymentProviderBaseRepository.Get(PaymentProviderId, CultureInfo.CurrentCulture,ContentState.Draft);
        }

        public static readonly ILogger Logger = new ObjectFactory<ILogger>().Get("ShopLogger");

        private readonly IOrderService<TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels> _orderService;

        public DesjardinsBeginPresenter(T view, IOrderService<TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels> orderService)
            : base(view)
        {
            _orderService = orderService;
        }

        public IOrderService<TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels> OrderService
        {
            get { return _orderService; }
        }

        private TOrder _order;

        protected virtual Guid Id
        {
            get { return PaymentProviderId; }
        }

        protected virtual string Name
        {
            get { return PaymentProviderName; }
        }

        protected virtual string MerchantKey
        {
            get { return CurrentNode.MerchantKey; }
        }

        protected abstract string ResponseURL { get; }

        protected abstract string CancelURL { get; }

        protected abstract string ErrorURL { get; }

        protected abstract string SuccessURL { get; }

        protected virtual string PaymentProviderURL
        {
            get { return CurrentNode.PaymentProviderUrl; }
        }



        protected override void Initialize(object sender, System.EventArgs e)
        {
            base.Initialize(sender, e);

            _order = OrderService.GetCurrentUpdatedOrNewOrder(Id, Name);

            if(_order != null)
            {
                if (String.IsNullOrEmpty(MerchantKey))
                {
                    throw new ArgumentNullException("MerchantKey");
                }

                var openSessionResult = Purchase.OpenSession(MerchantKey, _order.TransactionId, PaymentProviderURL);
                

                if (openSessionResult != null
                    && String.IsNullOrEmpty(openSessionResult.ErrorCode))
                {
                    Logger.Trace(openSessionResult.ServerResponse);

                    _order.PaymentProviderTransactionNumber = openSessionResult.PaymentProviderTransactionKey;//.PaymentProviderTransactionId
                    OrderService.SaveOrder(_order);


                    var tryPurchaseResult = Purchase.TryPurchase(openSessionResult.PaymentProviderMerchantId, MerchantKey,
                                                              _order.TransactionId,
                                                              openSessionResult.PaymentProviderTransactionKey,
                                                              _order.Total.Value,
                                                              CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
                                                              "", "", ResponseURL,
                                                              SuccessURL, CancelURL, ErrorURL, PaymentProviderURL);
                    Logger.Trace(tryPurchaseResult.ServerResponse);

                    View.Redirect(tryPurchaseResult.Url);
                }
                else
                {
                    View.ErrorMessage = "DesjardinsErrorResponse".Translate("Shop");
                }
            }
            else
            {
                View.ErrorMessage = "ErrorCreateOrder".Translate();               
            }
        }
    }
}
